package com.cvte.shop.service.impl;

import com.cvte.csb.core.interfaces.vo.RestResponse;
import com.cvte.csb.web.rest.ResponseFactory;
import com.cvte.shop.constants.UniversalMethodConstants;
import com.cvte.shop.constants.UniversalResultFieldsConstants;
import com.cvte.shop.entity.*;
import com.cvte.shop.exception.BaseBusinessException;
import com.cvte.shop.mapper.*;
import com.cvte.shop.service.UniversalMethodResultService;
import com.cvte.shop.service.UniversalTableConfigService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.cvte.csb.jdbc.mybatis.biz.BaseBiz;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.List;

/**
 * 服务实现类
 *
 * @author inv
 * @since 2020-08-04
 */
@Service
@Transactional
public class UniversalMethodResultServiceImpl extends BaseBiz<UniversalMethodResultMapper, UniversalMethodResult> implements UniversalMethodResultService {

    @Autowired
    private UniversalMethodResultMapper universalMethodResultMapper;

    @Autowired
    private UniversalTableConfigMapper universalTableConfigMapper;

    @Autowired
    private UniversalMethodConfigMapper universalMethodConfigMapper;

    @Autowired
    private UniversalBasicConditionMapper universalBasicConditionMapper;

    @Autowired
    private UniversalDefinedConditionMapper universalDefinedConditionMapper;

    @Autowired
    private UniversalTableConfigService universalTableConfigService;

    @Override
    public void createMethodResult(String tableId, String result,String viewId) {
        UniversalMethodResult universalMethodResult = new UniversalMethodResult();
        universalMethodResult.setSqlContext(result);
        universalMethodResult.setTableId(tableId);
        universalMethodResult.setViewId(viewId);
        universalMethodResultMapper.insert(universalMethodResult);
    }

    /**
     * 初次生成sql
     * @param fieldsList
     * @param tableId
     */
    @Override
    public void createInitTableSql(List<UniversalResultFields> fieldsList, String tableId, String viewId){
        // 生成拿出结果集
        String sql = createSql(fieldsList,tableId).toString();
        createMethodResult(tableId,sql,viewId);
    }

    @Override
    public void createInitViewSql(List<UniversalResultFields> fieldsList, String tableId, String viewId) {
        // 生成拿出结果集
        StringBuilder builder = createSql(fieldsList,tableId);
        // 取出条件变量
        List<UniversalDefinedCondition> definedConditionList = getDefinedCondition(tableId,UniversalResultFieldsConstants.DEAULT_VIEW_ID);
        List<UniversalBasicCondition> basicConditionList = getBasicCondition(tableId, UniversalResultFieldsConstants.DEAULT_VIEW_ID);
        if((definedConditionList != null && definedConditionList.size() != 0) || (basicConditionList != null && basicConditionList.size() != 0)){
            builder.append(" and (");
            // 创建新的sql
            boolean flag = universalTableConfigService.createBasicCondition(builder,basicConditionList);
            universalTableConfigService.createDefinedCondition(builder,definedConditionList,flag);
            builder.append(" ) ");
        }
        checkSql(builder.toString());
        createMethodResult(tableId,builder.toString(),viewId);
    }

    @Override
    public void checkSql(String resultSet) {
        universalTableConfigMapper.checkSql(resultSet);
    }

    @Override
    public RestResponse universalMethod(String viewId, HttpServletRequest request) {
        String methodName = getMethodNameByReq(request);

        // 查询方法的tableid
        UniversalMethodConfig querypParam = new UniversalMethodConfig();
        querypParam.setMethodName(methodName);
        UniversalMethodConfig methodConfig= universalMethodConfigMapper.selectOne(querypParam);

        // 验证请求方式是否符合要求
        String requestType = methodConfig.getRequestType();
        String methodType = request.getMethod().toUpperCase();
        if(requestType.equals(methodType)){
            // 查询对应的sql
            String sqlContext = universalMethodResultMapper.selectSqlContextByTableId(methodConfig.getTableId(),viewId);
            // 执行对应的sql
            List<HashMap<String,String>> resultList = universalMethodResultMapper.selectUniversalMethod(sqlContext);
            return ResponseFactory.getOkResponse(resultList);
        }else{
            throw new BaseBusinessException("500006","请求方式错误");
        }
    }




    @Override
    public String getResultResultSet(String tableId) {
        return universalTableConfigMapper.selectTableResultById(tableId);
    }

    @Override
    public List<UniversalDefinedCondition> getDefinedCondition(String tableId, String viewId) {
        UniversalDefinedCondition queryParam = new UniversalDefinedCondition();
        queryParam.setTableId(tableId);
        queryParam.setViewId(viewId);
        List<UniversalDefinedCondition> results = universalDefinedConditionMapper.select(queryParam);
        return results;
    }

    @Override
    public List<UniversalBasicCondition> getBasicCondition(String tableId, String viewId) {
        UniversalBasicCondition queryParam = new UniversalBasicCondition();
        queryParam.setTableId(tableId);
        queryParam.setViewId(viewId);
        List<UniversalBasicCondition> results = universalBasicConditionMapper.select(queryParam);
        return results;
    }

    private StringBuilder createSql(List<UniversalResultFields> fieldsList,String tableId){
        String resultSet = getResultResultSet(tableId);
        StringBuilder builder = new StringBuilder();
        builder.append("select ");
        for(int i = 0;i < fieldsList.size();i++){
            builder.append(fieldsList.get(i).getFieldName());
            if(i != fieldsList.size() - 1){
                builder.append(",");
            }
        }
        builder.append(" from ( ");
        builder.append(resultSet);
        builder.append(" )");
        builder.append(" where 1 = 1 ");
        // 验证sql是否能够执行
        String sql = builder.toString();
        checkSql(sql);
        return builder;
    }

    private String getMethodNameByReq(HttpServletRequest request) {
        String uri = request.getRequestURI();
        int pathLen = UniversalMethodConstants.UNIVERSAL_METHOD_PATH.length();
        String methodName = uri.substring(pathLen);
        return methodName;
    }

}
